// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.erosion.categories;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import zombie.erosion.ErosionData;
import zombie.erosion.obj.ErosionObj;
import zombie.erosion.obj.ErosionObjSprites;
import zombie.erosion.season.ErosionIceQueen;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoObject;
import zombie.iso.sprite.IsoSprite;

public final class NatureGeneric extends ErosionCategory {
    private ArrayList<ErosionObj> objs = new ArrayList();
    private static final int GRASS = 0;
    private static final int FERNS = 1;
    private static final int GENERIC = 2;
    private ArrayList<ArrayList<Integer>> objsRef = new ArrayList();
    private int[] spawnChance = new int[100];

    @Override
    public boolean replaceExistingObject(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall
    ) {
        int int0 = _sq.getObjects().size();

        for (int int1 = int0 - 1; int1 >= 1; int1--) {
            IsoObject isoObject = _sq.getObjects().get(int1);
            IsoSprite isoSprite = isoObject.getSprite();
            if (isoSprite != null && isoSprite.getName() != null && isoSprite.getName().startsWith("blends_grassoverlays")) {
                float float0 = 0.3F;
                float float1 = 12.0F;
                if ("Forest".equals(_sq.getZoneType())) {
                    float0 = 0.5F;
                    float1 = 6.0F;
                } else if ("DeepForest".equals(_sq.getZoneType())) {
                    float0 = 0.7F;
                    float1 = 3.0F;
                }

                NatureGeneric.CategoryData categoryData = (NatureGeneric.CategoryData)this.setCatModData(_sqErosionData);
                ArrayList arrayList = (ArrayList)this.objsRef.get(0);
                int int2 = _sqErosionData.noiseMainInt;
                int int3 = _sqErosionData.rand(_sq.x, _sq.y, 101);
                if ((float)int3 < (float)int2 / float1) {
                    if (_sqErosionData.magicNum < float0) {
                        arrayList = (ArrayList)this.objsRef.get(1);
                    } else {
                        arrayList = (ArrayList)this.objsRef.get(2);
                    }

                    categoryData.notGrass = true;
                    categoryData.maxStage = int2 > 60 ? 1 : 0;
                } else {
                    categoryData.maxStage = int2 > 67 ? 2 : (int2 > 50 ? 1 : 0);
                }

                categoryData.gameObj = (Integer)arrayList.get(_sqErosionData.rand(_sq.x, _sq.y, arrayList.size()));
                categoryData.stage = categoryData.maxStage;
                categoryData.spawnTime = 0;
                categoryData.dispSeason = -1;
                ErosionObj erosionObj = (ErosionObj)this.objs.get(categoryData.gameObj);
                isoObject.setName(erosionObj.name);
                isoObject.doNotSync = true;
                categoryData.hasSpawned = true;
                return true;
            }
        }

        return false;
    }

    @Override
    public boolean validateSpawn(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall, boolean _isRespawn
    ) {
        if (_sq.getObjects().size() > (_hasWall ? 2 : 1)) {
            return false;
        } else {
            int int0 = _sqErosionData.noiseMainInt;
            if (_sqErosionData.rand(_sq.x, _sq.y, 101) < this.spawnChance[int0]) {
                float float0 = 0.3F;
                float float1 = 12.0F;
                if ("Forest".equals(_sq.getZoneType())) {
                    float0 = 0.5F;
                    float1 = 6.0F;
                } else if ("DeepForest".equals(_sq.getZoneType())) {
                    float0 = 0.7F;
                    float1 = 3.0F;
                }

                NatureGeneric.CategoryData categoryData = (NatureGeneric.CategoryData)this.setCatModData(_sqErosionData);
                ArrayList arrayList = (ArrayList)this.objsRef.get(0);
                int int1 = _sqErosionData.rand(_sq.x, _sq.y, 101);
                if ((float)int1 < (float)int0 / float1) {
                    if (_sqErosionData.magicNum < float0) {
                        arrayList = (ArrayList)this.objsRef.get(1);
                    } else {
                        arrayList = (ArrayList)this.objsRef.get(2);
                    }

                    categoryData.notGrass = true;
                    categoryData.maxStage = int0 > 60 ? 1 : 0;
                } else {
                    categoryData.maxStage = int0 > 67 ? 2 : (int0 > 50 ? 1 : 0);
                }

                categoryData.gameObj = (Integer)arrayList.get(_sqErosionData.rand(_sq.x, _sq.y, arrayList.size()));
                categoryData.stage = 0;
                categoryData.spawnTime = 100 - int0;
                return true;
            } else {
                return false;
            }
        }
    }

    @Override
    public void update(IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionCategory.Data _sqCategoryData, ErosionData.Chunk _chunkData, int _eTick) {
        NatureGeneric.CategoryData categoryData = (NatureGeneric.CategoryData)_sqCategoryData;
        if (_eTick >= categoryData.spawnTime && !categoryData.doNothing) {
            if (categoryData.gameObj >= 0 && categoryData.gameObj < this.objs.size()) {
                ErosionObj erosionObj = (ErosionObj)this.objs.get(categoryData.gameObj);
                int int0 = categoryData.maxStage;
                int int1 = (int)Math.floor((double)((float)(_eTick - categoryData.spawnTime) / ((float)erosionObj.cycleTime / ((float)int0 + 1.0F))));
                if (int1 > int0) {
                    int1 = int0;
                }

                if (int1 >= erosionObj.stages) {
                    int1 = erosionObj.stages - 1;
                }

                if (categoryData.stage == categoryData.maxStage) {
                    int1 = categoryData.maxStage;
                }

                int int2 = 0;
                if (!categoryData.notGrass) {
                    int2 = this.currentSeason(_sqErosionData.magicNum, erosionObj);
                    int int3 = this.getGroundGrassType(_sq);
                    if (int3 == 2) {
                        int2 = Math.max(int2, 3);
                    } else if (int3 == 3) {
                        int2 = Math.max(int2, 4);
                    }
                }

                boolean boolean0 = false;
                boolean boolean1 = false;
                this.updateObj(_sqErosionData, _sqCategoryData, _sq, erosionObj, boolean0, int1, int2, boolean1);
            } else {
                categoryData.doNothing = true;
            }
        }
    }

    @Override
    public void init() {
        for (int int0 = 0; int0 < 100; int0++) {
            this.spawnChance[int0] = (int)this.clerp((float)(int0 - 0) / 100.0F, 0.0F, 99.0F);
        }

        this.seasonDisp[5].season1 = 5;
        this.seasonDisp[5].season2 = 0;
        this.seasonDisp[5].split = false;
        this.seasonDisp[1].season1 = 1;
        this.seasonDisp[1].season2 = 0;
        this.seasonDisp[1].split = false;
        this.seasonDisp[2].season1 = 2;
        this.seasonDisp[2].season2 = 3;
        this.seasonDisp[2].split = true;
        this.seasonDisp[4].season1 = 4;
        this.seasonDisp[4].season2 = 5;
        this.seasonDisp[4].split = true;
        int[] int1 = new int[]{1, 2, 3, 4, 5};
        int[] int2 = new int[]{2, 1, 0};

        for (int int3 = 0; int3 < 3; int3++) {
            this.objsRef.add(new ArrayList());
        }

        for (int int4 = 0; int4 <= 5; int4++) {
            ErosionObjSprites erosionObjSprites0 = new ErosionObjSprites(3, "Grass", false, false, false);

            for (int int5 = 0; int5 < int1.length; int5++) {
                for (int int6 = 0; int6 < int2.length; int6++) {
                    int int7 = 0 + int5 * 18 + int6 * 6 + int4;
                    erosionObjSprites0.setBase(int2[int6], "e_newgrass_1_" + int7, int1[int5]);
                }
            }

            ErosionObj erosionObj0 = new ErosionObj(erosionObjSprites0, 60, 0.0F, 0.0F, false);
            this.objs.add(erosionObj0);
            ((ArrayList)this.objsRef.get(0)).add(this.objs.size() - 1);
        }

        for (int int8 = 0; int8 <= 15; int8++) {
            ErosionObjSprites erosionObjSprites1 = new ErosionObjSprites(2, "Generic", false, false, false);

            for (int int9 = 0; int9 <= 1; int9++) {
                int int10 = int9 * 16 + int8;
                erosionObjSprites1.setBase(int9, "d_generic_1_" + int10, 0);
            }

            ErosionObj erosionObj1 = new ErosionObj(erosionObjSprites1, 60, 0.0F, 0.0F, true);
            this.objs.add(erosionObj1);
            ((ArrayList)this.objsRef.get(2)).add(this.objs.size() - 1);
        }

        ErosionIceQueen erosionIceQueen = ErosionIceQueen.instance;

        for (int int11 = 0; int11 <= 7; int11++) {
            ErosionObjSprites erosionObjSprites2 = new ErosionObjSprites(2, "Fern", true, false, false);

            for (int int12 = 0; int12 <= 1; int12++) {
                int int13 = 48 + int12 * 32 + int11;
                erosionObjSprites2.setBase(int12, "d_generic_1_" + int13, 0);
                erosionIceQueen.addSprite("d_generic_1_" + int13, "d_generic_1_" + (int13 + 16));
            }

            ErosionObj erosionObj2 = new ErosionObj(erosionObjSprites2, 60, 0.0F, 0.0F, true);
            this.objs.add(erosionObj2);
            ((ArrayList)this.objsRef.get(1)).add(this.objs.size() - 1);
        }
    }

    @Override
    protected ErosionCategory.Data allocData() {
        return new NatureGeneric.CategoryData();
    }

    private int toInt(char _char) {
        switch (_char) {
            case '0':
                return 0;
            case '1':
                return 1;
            case '2':
                return 2;
            case '3':
                return 3;
            case '4':
                return 4;
            case '5':
                return 5;
            case '6':
                return 6;
            case '7':
                return 7;
            case '8':
                return 8;
            case '9':
                return 9;
            default:
                return 0;
        }
    }

    private int getGroundGrassType(IsoGridSquare isoGridSquare) {
        IsoObject isoObject = isoGridSquare.getFloor();
        if (isoObject == null) {
            return 0;
        } else {
            IsoSprite isoSprite = isoObject.getSprite();
            if (isoSprite != null && isoSprite.getName() != null && isoSprite.getName().startsWith("blends_natural_01_")) {
                int int0 = 0;

                for (int int1 = 18; int1 < isoSprite.getName().length(); int1++) {
                    int0 += this.toInt(isoSprite.getName().charAt(int1));
                    if (int1 < isoSprite.getName().length() - 1) {
                        int0 *= 10;
                    }
                }

                int int2 = int0 / 8;
                int int3 = int0 % 8;
                if (int2 == 2 && (int3 == 0 || int3 >= 5)) {
                    return 1;
                }

                if (int2 == 4 && (int3 == 0 || int3 >= 5)) {
                    return 2;
                }

                if (int2 == 6 && (int3 == 0 || int3 >= 5)) {
                    return 3;
                }
            }

            return 0;
        }
    }

    @Override
    public void getObjectNames(ArrayList<String> list) {
        for (int _int = 0; _int < this.objs.size(); _int++) {
            if (((ErosionObj)this.objs.get(_int)).name != null && !list.contains(((ErosionObj)this.objs.get(_int)).name)) {
                list.add(((ErosionObj)this.objs.get(_int)).name);
            }
        }
    }

    private static final class CategoryData extends ErosionCategory.Data {
        public int gameObj;
        public int maxStage;
        public int spawnTime;
        public boolean notGrass;

        @Override
        public void save(ByteBuffer byteBuffer) {
            super.save(byteBuffer);
            byteBuffer.put((byte)this.gameObj);
            byteBuffer.put((byte)this.maxStage);
            byteBuffer.putShort((short)this.spawnTime);
            byteBuffer.put((byte)(this.notGrass ? 1 : 0));
        }

        @Override
        public void load(ByteBuffer byteBuffer, int _int) {
            super.load(byteBuffer, _int);
            this.gameObj = byteBuffer.get();
            this.maxStage = byteBuffer.get();
            this.spawnTime = byteBuffer.getShort();
            this.notGrass = byteBuffer.get() == 1;
        }
    }
}
